package org.quickjsf.spring;

import javax.faces.context.FacesContext;

import org.apache.log4j.Logger;
import org.quickjsf.common.util.FacesUtil;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.beans.factory.config.Scope;

public class ViewScope implements Scope {
	
	private static Logger logger = Logger.getLogger(ViewScope.class);
	
    public final String VIEW_SCOPE_KEY = "CRANK_VIEW_SCOPE";  
    public final String VIEW_STATE_VALUE = "CRANK_VIEW_STATE";  
    
    public Object get(String name, ObjectFactory<?> objectFactory)   
    {          
        if (FacesContext.getCurrentInstance().getViewRoot() != null) {
        	String view_scope_key = VIEW_SCOPE_KEY + name;
        	String view_state_value = VIEW_STATE_VALUE + name;
        	String viewState = FacesUtil.getRequestParameter("javax.faces.ViewState");
        	//first time view request or session invalidated after view request 
        	if (viewState == null || FacesUtil.getObjectInSession(view_scope_key) == null ) {
                Object object = objectFactory.getObject();   
                FacesUtil.setObjectInSession(view_state_value, view_state_value);
                FacesUtil.setObjectInSession(view_scope_key, object);
                return object;
             //second time view request
        	} else if (FacesUtil.getObjectInSession(view_state_value).equals(view_state_value)) {
        		 FacesUtil.setObjectInSession(view_state_value, viewState);
        		 return FacesUtil.getObjectInSession(view_scope_key);
        	// view changed  after request 	 
        	} else if (!FacesUtil.getObjectInSession(view_state_value).equals(viewState)) {
                Object object = objectFactory.getObject();   
                FacesUtil.setObjectInSession(view_state_value, viewState);
                FacesUtil.setObjectInSession(view_scope_key, object);
                return object;
            // the same view request    
        	} else {
        		return FacesUtil.getObjectInSession(view_scope_key);
        	}
        } else {
        	logger.debug("################ : GET VIEW ROOT NOT FOUND");       
   		 	return null;
        }    
    }       
      
    public String getConversationId()   
    {      
        return null;     
    }       
      
    public void registerDestructionCallback(String name, Runnable callback)   
    {      
    	logger.debug("#####################: We don't support destruction callbacks at this time");     
    }       
      
    public Object remove(String name)   
    {      
        if (FacesContext.getCurrentInstance().getViewRoot() != null) {       
        	FacesUtil.removeObjectInSession(VIEW_STATE_VALUE);
    		return FacesUtil.removeObjectInSession(VIEW_SCOPE_KEY);
        } else {       
        	logger.debug("################ : REMOVE VIEW ROOT NOT FOUND");       
            return null;      
        }     
    }
	@Override
	public Object resolveContextualObject(String arg0) {
		return null;
	}      
}
